/*
 * @Author: your name
 * @Date: 2021-03-31 09:20:21
 * @LastEditTime: 2021-04-16 09:00:42
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \tower_defense\assets\scripts\game_scene\tower\electricity_bullet.ts
 */

import { UG } from "../../modules/ugame"
import { ElectricityBulletParams } from "../../game_data/tower_data/electricity_bullet_params";
import Enemy from "../enemy/enemy";
import { FrameAnim } from "../../common/frame_anim";

const { ccclass, property } = cc._decorator;

// 自定义类
@ccclass("electricity_bullet_skin")
class electricity_bullet_skin {
    @property(cc.SpriteFrame)   // 子弹精灵图片
    public electricity_bullet_icon: cc.SpriteFrame = null;
}

@ccclass
export class ElectricityBullet extends cc.Component {

    @property(cc.Integer)   // 子弹移动速度
    public speed: number = 200;

    @property(cc.Integer)   // 子弹攻击力
    public attack: number = 10;

    @property(cc.Integer)  // 子弹等级
    public bullet_level: number = 1;

    @property(cc.Node)          // 子弹精灵节点
    public anim_node: cc.Node = null;

    @property(cc.Integer)
    public bullet_effect_sample: number = 10;    // 子弹效果帧速率

    @property(cc.SpriteFrame)   // 子弹效果资源
    public bullet_effect_anim: Array<cc.SpriteFrame> = [];

    @property({
        type: electricity_bullet_skin,
    })
    public level_bullet_skin = [];   // 每个等级子弹皮肤

    public bullet_root_node: cc.Node = null;    // 子弹存放节点
    public shoot_enemy: cc.Node = null;         // 敌人

    public electricity_bullet_frame_anim: FrameAnim = null;    // 保存自定义动画组件

    onLoad() {
        this.bullet_root_node = cc.find('Canvas/tower_panel/bullet_root');
        this._set_bullet_skin_by_level();

        // 绑定自定义动画组件
        this.electricity_bullet_frame_anim = this.anim_node.addComponent(FrameAnim);
        this.electricity_bullet_frame_anim.sprite_com = this.anim_node.getComponent(cc.Sprite);
        this.electricity_bullet_frame_anim.anim_com = this.anim_node.getComponent(cc.Animation);
    }

    // 设置炮弹皮肤
    private _set_bullet_skin_by_level(): void {
        this.anim_node.getComponent(cc.Sprite).spriteFrame = this.level_bullet_skin[this.bullet_level - 1].electricity_bullet_icon;
    }

    // 子弹射击
    public shoot(level: number, bullet_world_pos: cc.Vec2, enemy_world_pos: cc.Vec2, enemy: cc.Node): void {
        // 
        this.electricity_bullet_frame_anim.sprite_frame_arr = this.bullet_effect_anim;
        this.electricity_bullet_frame_anim.sample = this.bullet_effect_sample;

        // 子弹参数
        this.bullet_level = level;
        this.speed = ElectricityBulletParams[this.bullet_level - 1].speed;
        this.attack = ElectricityBulletParams[this.bullet_level - 1].attack;
        this.shoot_enemy = enemy;

        this._set_bullet_skin_by_level();

        // 把敌人，转换成和子弹同一个坐标系下
        let start_pos: cc.Vec2 = this.bullet_root_node.parent.convertToNodeSpaceAR(bullet_world_pos);
        let end_pos: cc.Vec2 = this.bullet_root_node.parent.convertToNodeSpaceAR(enemy_world_pos);

        // 调整位置
        this.node.setPosition(start_pos);
        
        // 初始化
        this.anim_node.width = 81;
        this.anim_node.scaleX = 1;
        this.anim_node.angle = 0;

        // 计算参数
        let dir: cc.Vec2 = enemy_world_pos.sub(bullet_world_pos);
        let len: number = dir.mag();                    // 向量差长度
        let time: number = len / this.speed;            // 求运动时间

        if (this.shoot_enemy) {
            let enemy_com: Enemy = this.shoot_enemy.getComponent(Enemy);
            enemy_world_pos = this.shoot_enemy.parent.convertToWorldSpaceAR(cc.v2(this.shoot_enemy.x, this.shoot_enemy.y));
            end_pos = enemy_com.walk_pos_by_time(time);
        }

        // 计算角度
        let comVec = new cc.Vec2(1, 0);// 选择x轴正方向作为夹角计算的参考方向
        dir = enemy_world_pos.sub(bullet_world_pos);
        len = dir.mag();                    // 向量差长度
        let radian = dir.angle(comVec);//获得不带方向的夹角弧度值(参考方向顺时针为正值，逆时针为负值)
        let degree = Math.floor(cc.misc.radiansToDegrees(radian));

        // 改变闪电的宽度，射击闪电
        if (end_pos.y <= start_pos.y) {  // 敌人在下 （0，-180）
            // 微调
            if (Math.abs(start_pos.y - end_pos.y) >= 10) {  
                degree = -degree;
            } else {
                degree = -degree - 10;
            }
        } else { // 敌人在上 （0，180）
            degree = degree + 2;
        }

        this.anim_node.angle = degree;
        this.anim_node.scaleX = len / this.anim_node.width;

        this.electricity_bullet_frame_anim.play_once(() => {
            // 伤害计算
            this._on_bullet_shoot_enemy();
        });
    }

    // 伤害计算
    public _on_bullet_shoot_enemy(): void {
        if (!this.shoot_enemy || !UG.is_enemy_active(this.shoot_enemy)) {
            return;
        }

        // 击中怪物
        let enemy: Enemy = this.shoot_enemy.getComponent(Enemy);
        enemy.on_electricity_attacked(ElectricityBulletParams[this.bullet_level - 1].attack);

        // 移除子弹，可以改用节点池
        this.node.destroy();
    }
}